package controller.simulationcontroller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

import view.simulationview.ProgressWindow;
import view.simulationview.SimulationArea;

import model.simulationmodel.LogicValue;
import model.simulationmodel.SimulationModel;

import controller.commoncontroller.UtilityDialogs;

/**
 * Listener der auf dem Button zum exportieren der Wahrheitstabelle als CSV-Datei liegt.
 * 
 * @author Team Locsi
 *
 */
public class ExportTruthTableAsCSVListener implements ActionListener {

	/**
	 * Referenz auf die SimulationArea
	 */
	private SimulationArea sArea;
	
	/**
	 * Referenz auf das SimulationModel
	 */
	private SimulationModel simModel;
	
	/**
	 * Referenz auf das zweidimensionale Array mit den logischen Werten
	 */
	private LogicValue[][] tTable;
	
	/**
	 * Referenz auf das Array der Namen der Schalter/Taktgeber und Lampen
	 */
	private String[] names;

	/**
	 * Konstruktur mit den benoetigten Referenzen
	 * 
	 * @param sArea <code>SimulationArea</code> 
	 * @param simModel <code>Simulationmodel</code>
	 * @param tTable <code>LogicValue[][]</code>
	 * @param names <code>String[]</code>
	 */
	public ExportTruthTableAsCSVListener(SimulationArea sArea,
			SimulationModel simModel, LogicValue[][] tTable, String[] names) {
		this.sArea = sArea;
		this.simModel = simModel;
		this.tTable = tTable;
		this.names = names;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		final StringBuilder toSave = new StringBuilder();
		BufferedWriter writerx = null;

		try {
			String path = UtilityDialogs.save2Dialog(sArea,
					UtilityDialogs.CSV_EXTENSION, simModel.getCircuitName());
			if (path == null) {
				return;
			}
			writerx = new BufferedWriter(new FileWriter(path));
		} catch (IOException e2) {
			e2.printStackTrace();
		}

		final BufferedWriter writer = writerx;
		Thread saveCSVthread = null;
		
		final ProgressWindow prog = new ProgressWindow(simModel,
				UtilityDialogs.getFrame(), 0, tTable.length);
		
		//in einem eigenen Thread wird die tabelle in eine csv-datei geschrieben
		saveCSVthread = new Thread() {
			@Override
			public void run() {
				for (int i = 0; i < names.length; i++) {
					if (i != names.length - 1) {
						toSave.append(names[i]);
						toSave.append(";");
					} else {
						toSave.append(names[i]);
					}
				}
				toSave.append(System.getProperty("line.separator"));
				for (int i = 0; i < tTable.length; i++) {
					for (int j = 0; j < tTable[i].length; j++) {
						if (j != tTable[i].length - 1) {
							toSave.append(tTable[i][j]);
							toSave.append(";");
						} else {
							toSave.append(tTable[i][j]);
						}
					}
					prog.setValue(i);
					toSave.append(System.getProperty("line.separator"));
					
					//wenn nurnoch 60% des verfügbaren arbeitsspeichers voll sind
					//wird der bisher in den stringBuilder geladene Inhalt der tabelle
					//in die datei geschrieben
					if (Runtime.getRuntime().freeMemory() <= Runtime
							.getRuntime().maxMemory() * 0.6) {
						try {
							writer.write(toSave.toString());
							toSave.delete(0, toSave.length());
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
				try {
					writer.write(toSave.toString());
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				toSave.delete(0, toSave.length());
				if (prog != null) {
					prog.dispose();
				}
			}
		};
		saveCSVthread.start();
	}
}
